import QtQuick
import QtQuick.Layouts
import QtCharts

Rectangle {
    Layout.fillWidth: true
    Layout.fillHeight: true

    // 数据定义：原始数据数组
    property var rawData: [
        [18, 29, 28, 22, 35, 65, 40, 45, 41, 52, 38, 100], // 手机（含离群值100）
        [8, 12, 15, 18, 20, 25, 28, 30, 32, 35, 42, 70],       // 平板（含离群值70）
        [30, 42, 48, 55, 58, 59, 61, 63, 65, 66, 70, 100]  // 笔记本（含离群值30,100）
    ]

    // 计算箱线图统计数据的函数
    function calculateBoxPlotStats(rawData) {
        // 1. 排序
        let sorted = [...rawData].sort((a, b) => a - b)
        let n = sorted.length
        // console.log("sorted: ", sorted)

        // 2. 计算中位数
        let median = n % 2 === 0
            ? (sorted[n/2 - 1] + sorted[n/2]) / 2
            : sorted[Math.floor(n/2)]
        // console.log("median: ", median)

        // 3. 计算Q1和Q3
        let q1Index = Math.floor(n / 4)
        let q3Index = Math.floor(3 * n / 4)
        let q1 = n % 4 === 0
            ? (sorted[q1Index - 1] + sorted[q1Index]) / 2
            : sorted[q1Index]
        let q3 = n % 4 === 0
            ? (sorted[q3Index - 1] + sorted[q3Index]) / 2
            : sorted[q3Index]
        // console.log("q1: ", q1)
        // console.log("q3: ", q3)

        // 4. 计算IQR和上下边缘
        let iqr = q3 - q1
        let upperFence = q3 + 1.5 * iqr
        let lowerFence = q1 - 1.5 * iqr

        // console.log("lowerFence: ", lowerFence)
        // console.log("upperFence: ", upperFence)

        // 5. 识别离群值和调整后的最小最大值
        let outliers = []
        let adjustedMin = Infinity
        let adjustedMax = -Infinity

        for (let i = 0; i < sorted.length; i++) {
            let val = sorted[i]
            if (val < lowerFence || val > upperFence) {
                outliers.push(val)  // 离群值
            } else {
                adjustedMin = Math.min(adjustedMin, val)
                adjustedMax = Math.max(adjustedMax, val)
            }
        }
        // console.log("outliers: ", outliers)
        // console.log("--------------------------------")

        return {
            min: adjustedMin,
            q1: q1,
            median: median,
            q3: q3,
            max: adjustedMax,
            outliers: outliers,
            iqr: iqr,
            upperFence: upperFence,
            lowerFence: lowerFence
        }
    }

    ChartView {
        id: chartView
        title: "带离群值的箱线图"
        titleFont.bold: true
        titleFont.pointSize: 16

        anchors.fill: parent
        antialiasing: true
        legend.visible: true
        legend.alignment: Qt.AlignBottom

        // Y轴
        ValueAxis {
            id: valueAxisY
            titleText: "销售额 (万元)"
            min: 0
            max: 110
            tickCount: 12
            labelFormat: "%.0f"
        }

        // X轴
        BarCategoryAxis {
            id: valueAxisX
            categories: ["智能手机", "平板电脑", "笔记本"]
            titleText: "产品类别"
        }

        // 主箱线系列
        BoxPlotSeries {
            id: plotSeries
            name: "销售额分布"
            axisX: valueAxisX
            axisY: valueAxisY
            boxOutlineVisible: true
            boxWidth: 0.5

            Component.onCompleted: {
                // 为每个类别创建BoxSet
                for (let i = 0; i < rawData.length; i++) {
                    let stats = calculateBoxPlotStats(rawData[i])

                    // 创建箱线（使用调整后的五数）
                    let boxSet = boxSetFactory.createObject(plotSeries,
                        {   values: [stats.min, stats.q1, stats.median, stats.q3, stats.max],
                            label: valueAxisX.categories[i]
                        })
                    plotSeries.append(boxSet)

                    // 添加离群值到散点系列
                    for (let j = 0; j < stats.outliers.length; j++) {
                        // X坐标使用类别索引，Y坐标使用离群值
                        outlierSeries.append(i, stats.outliers[j])
                    }
                }
            }

            // 动态创建BoxSet的组件
            Component {
                id: boxSetFactory
                BoxSet {}
            }

            // 点击交互
            onClicked: function(boxSet) {
                let index = valueAxisX.categories.indexOf(boxSet.label)
                if (index === -1) {
                    console.log("index: ", index)
                    return
                }

                let stats = calculateBoxPlotStats(rawData[index])
                console.log("点击了: ", boxSet.label)
                console.log("├ 最小值: ", boxSet.values[BoxSet.LowerExtreme], "万")
                console.log("├ 下四分位数(Q1): ", boxSet.values[BoxSet.LowerQuartile], "万")
                console.log("├ 中位数: ", boxSet.values[BoxSet.Median], "万")
                console.log("├ 上四分位数(Q3): ", boxSet.values[BoxSet.UpperQuartile], "万")
                console.log("└ 最大值: ", boxSet.values[BoxSet.UpperExtreme], "万")

                console.log(`IQR(四分位距): ${stats.iqr.toFixed(1)} `)
                console.log(`范围（调整后）: [${stats.lowerFence} ~ ${stats.upperFence}]`)
                console.log(`离群值: ${stats.outliers.length > 0 ? `${stats.outliers.join(', ')}` : "无"}`)
            }
        }

        // 离群值散点系列
        ScatterSeries {
            id: outlierSeries
            name: "离群值"
            axisX: valueAxisX
            axisY: valueAxisY
            markerSize: 10
            color: "#E74C3C"
            borderColor: "#C0392B"
            borderWidth: 1
        }
    }
}
